using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Dream.ScenesLoader.SceneData;
using UnityEngine;

//System.Linq.Expressions
//���ڱ�ʾ�Ͳ�������ʽ����
//����ʽ����һ�����ݽṹ��
//����һ�����νṹ��ʾ���롣
//���ֱ�ʾ��������������ʱ�����ִ�д��룬
//���߶Դ�����ж�̬�������޸ġ�

namespace Light
{
    //�¼������
    public static class GameEventPool<T> where T : new()
    {
        private static readonly HashSet<T> _poolSet = new();
        private static readonly Stack<T> _pool = new();
        private static readonly Action<T> _init;

        static GameEventPool()
        {
            //��ȡT������
            var type = typeof(T);
            //��ȡType�����е����й�����ʵ���ֶε�FieldInfo�Ķ�������
            var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Instance);

            //��������ʽ���б�
            var expressions = new List<Expression>();
            //�������ʽ����������ΪT������Ϊvalue
            var param = Expression.Parameter(typeof(T), "value");
            //
            foreach (var fieldInfo in fieldInfos)
            {
                //��������ʽ�����ڷ��ʲ���param����ΪfieldInfo���ֶ�
                var field = Expression.Field(param, fieldInfo);
                //Expression.Default(fieldInfo.FieldType)����һ����ʾ�ֶ�Ĭ��ֵ�ı���ʽ����������Ϊnull��ֵ����Ϊ���Ƕ�Ӧ����ֵ��
                //Expression.Assign(field, ...)����һ����ֵ����ʽ
                //Add()����ֵ����ʽ����expressions�б���
                expressions.Add(Expression.Assign(field, Expression.Default(fieldInfo.FieldType)));
            }

            //�����еı���ʽ������һ������ʽ��
            var body = Expression.Block(expressions);
            //����Lambda����ʽ,����ΪAction<T>��ί�����ͣ�Compile()�������ɿ�ִ��ί��
            _init = Expression.Lambda<Action<T>>(body, param).Compile();
        }

        public static void Push(T item)
        {
            if (_poolSet.Contains(item)) return;

            _init.Invoke(item);
            _poolSet.Add(item);
            _pool.Push(item);
        }

        public static T Get()
        {
            if (_pool.Count > 0) return _pool.Pop();

            return new T();
        }
    }

    //�¼����࣬���ڻ�ȡ�¼�ID
    public class GameEventBase
    {
        private static int _eventCount;

        public static int GetEventId()
        {
            return ++_eventCount;
        }
    }

    //�¼��࣬ʹ��ʱ��Ҫ�̳д���
    public class GameEvent<T> : GameEventBase, IDisposable where T : GameEvent<T>, new()
    {
        public static int eventId;

        static GameEvent()
        {
            eventId = GetEventId();
        }

        //�̳�IDisposableʱ��Ҫʵ�ֵĺ���
        public void Dispose()
        {
            GameEventPool<T>.Push((T)this);
        }

        //��ȡ�¼�
        public static T Get()
        {
            return GameEventPool<T>.Get();
        }

        //�����¼�
        public static void Push(T item)
        {
            GameEventPool<T>.Push(item);
        }
    }

    public class StatusBarEvent : GameEvent<StatusBarEvent>
    {
        //����
        public FunctionBarOperationType BarOperationType;

        //����
        public FunctionBarType BarType;

        //��������ķ���
        public List<FunctionBarContentType> contentTypes;
    }

    /// <summary>
    ///     Ψһ�����þ���֪ͨPanel���´�
    /// </summary>
    public class GoodsPanelReOpenEvent : GameEvent<GoodsPanelReOpenEvent>
    {
    }

    public class GoodsBarSwtichItemEvent : GameEvent<GoodsBarSwtichItemEvent>
    {
        public AbstractItemSO item;

        public FunctionBarContentType originType;

        public FunctionBarContentType targetType;
    }

    public class GoodsBarDeleteItemEvent : GameEvent<GoodsBarDeleteItemEvent>
    {
        public AbstractItemSO item;
    }

    /// <summary>
    ///     ��Ҫ��С��ͼ������е���
    /// </summary>
    public class PlayerRegisterEvent : GameEvent<PlayerRegisterEvent>
    {
        /// <summary>
        ///     ��Ҫ����׷�ٵ�Transform
        /// </summary>
        public Transform transform;
    }

    public class EnemyRegisterEvnet : GameEvent<EnemyRegisterEvnet>
    {
        /// <summary>
        ///     ��Ҫ����׷�ٵ�Transform
        /// </summary>
        public Transform transform;
    }

    /// <summary>
    ///     ����ɾ��
    /// </summary>
    public class EnemyDeleteEvent : GameEvent<EnemyDeleteEvent>
    {
        public Transform transform;
    }

    /// <summary>
    ///     Itemװ��
    /// </summary>
    public class ItemEquipEvent : GameEvent<ItemEquipEvent>
    {
        public AbstractItemSO item;
    }

    /// <summary>
    ///     Itemȡ��
    /// </summary>
    public class ItemRelieveEvent : GameEvent<ItemRelieveEvent>
    {
        public AbstractItemSO item;
    }

    /// <summary>
    ///     item��ɾ��
    /// </summary>
    public class ItemDeleteEvent : GameEvent<ItemDeleteEvent>
    {
        public AbstractItemSO item;
    }

    public class QuickSlotPanelInitEvent : GameEvent<QuickSlotPanelInitEvent>
    {
    }

    public class QuickUpdateItemJsonIndexEvent : GameEvent<QuickUpdateItemJsonIndexEvent>
    {
        /// <summary>
        ///     Ŀ������
        /// </summary>
        public int index;

        /// <summary>
        ///     Ŀ������
        /// </summary>
        public AbstractItemSO item;
    }

    /// <summary>
    ///     ��������ʱ����
    /// </summary>
    public class UnolockSkillEvent : GameEvent<UnolockSkillEvent>
    {
        /// <summary>
        ///     �����ļ���
        /// </summary>
        public SkillItemSO skill;
    }

    /// <summary>
    ///     �л�װ��������
    ///     <para>���itemΪ�գ�����ʹ��ȭͷ</para>
    /// </summary>
    public class WeaponChangeEvent : GameEvent<WeaponChangeEvent>
    {
        /// <summary>
        ///     ����
        /// </summary>
        public AbstractItemSO item;

        /// <summary>
        ///     ��������
        ///     <para>���ܷ���</para>
        /// </summary>
        public WeaponDataSO weapon;

        ///// <summary>
        ///// ������߻�������,���������Ƿ����װ��
        ///// </summary>
        //public ItemType type;
    }

    /// <summary>
    ///     ������������
    /// </summary>
    public class DeathEvent : GameEvent<DeathEvent>
    {
        public Transform transform;
    }

    /// <summary>
    ///     ����ģʽ
    /// </summary>
    public class DayNightEvent : GameEvent<DayNightEvent>
    {
    }

    /// <summary>
    ///     ҹ��ģʽ
    /// </summary>
    public class NightEvent : GameEvent<NightEvent>
    {
    }

    /// <summary>
    ///     ʰȡװ�����͵�����
    /// </summary>
    public class PickItemsToBackPack : GameEvent<PickItemsToBackPack>
    {
        /// <summary>
        ///     ����
        /// </summary>
        public List<AbstractItemSO> items;
    }

    public class LoadNewScences : GameEvent<LoadNewScences>
    {
    }


    public class ProductResultEvent : GameEvent<ProductResultEvent>
    {
        public bool isComplated = false;

        public int pointsChange;
    }

    //sky 24-11-26 16:24:32 
    public class SceneLoadEvent : GameEvent<SceneLoadEvent>
    {
        public bool isExitScene = false;

        public bool isFadeScreen = true;

        public GameSceneSO sceneData;
    }

    //sky 24-11-26 16:24:28 
    public class NextSceneLoad : GameEvent<NextSceneLoad>
    {
        public bool isExitScene;
        public bool isFadeScreen;
        public int sceneDataIndex;
    }

    //sky 24-11-26 16:24:41
    public class IsAwake : GameEvent<IsAwake>
    {
        public bool isSleepOrAwake;
    }

    //mao 24-11-25 03:32
    public class ProductCreateEvent : GameEvent<ProductCreateEvent>
    {
        public string productName;
    }

    //mao 24-11-28 04:44
    /// <summary>
    ///     发送一次在BossController中记录一个Boss的销毁
    /// </summary>
    public class BossDestroyEvent : GameEvent<BossDestroyEvent>
    {
    }

    public class EnterNextWaveEvent : GameEvent<EnterNextWaveEvent>
    {
    }

    public class OpenSummaryPanelEvent : GameEvent<OpenSummaryPanelEvent>
    {
    }

    public class EnterEndingPanelEvent : GameEvent<EnterEndingPanelEvent>
    {
        /// <summary>
        ///     判断是否进入最终的结束语
        /// </summary>
        public bool isEnding = false;
    }

    /// <summary>
    ///     同时开启第一场景
    /// </summary>
    public class LoadFirstSceneEvent : GameEvent<LoadFirstSceneEvent>
    {
    }
}